library ItemPickDropEngine initializer init requires  GlobalVariables, SoundSystemLegacy, NOTDAWorldPhysics


	private function InItemList takes integer itemid, string itemlist returns boolean
		return GetB(itemlist,itemid)
	endfunction

	private function HasUnitItem takes unit u, integer itemid, string itemlist returns boolean
		local integer A = 0
		local integer itemcount = 0
		loop
			exitwhen A==6
			if InItemList(GetItemTypeId(UnitItemInSlot(u, A)),itemlist) then
				set itemcount = itemcount + 1
				if itemcount>1 then
					return true
				endif
			endif
			set A = A + 1
		endloop
		return InItemList(GetUnitTypeId(u),itemlist)
	endfunction

	private function CanPickup takes unit u, integer itemid, string itemlist returns boolean
		return InItemList(itemid,itemlist) and HasUnitItem(u,itemid,itemlist)
	endfunction
	
	private function ValidItem takes unit u, item i returns boolean
		local integer a = 1
		local integer itemid = GetItemTypeId(i)
		loop
			exitwhen a>udg_nItemLists
			if CanPickup(u,itemid,udg_ItemLists[a]) then
				return false
			endif
			set a=a+1
		endloop
		return true
	endfunction

	
	private function GetUnitItem takes unit u, integer itemId returns item
		local integer slot = 0
		local item i
		loop
			set i = UnitItemInSlot(u,slot)
			if i!=null and GetItemTypeId(i)==itemId then
				exitwhen 1==1
			endif
			set slot = slot + 1
			exitwhen slot == 6
		endloop
		if i!=null then
			set i = null
		endif
		if slot==6 then
			return null
		else
			return UnitItemInSlot(u,slot)
		endif
	endfunction

	private function Stack takes unit u, item pick, integer itemid, integer box, integer single, integer max returns boolean
		local item inv
		local integer n
		local integer n2
		local integer inven = 0
		local boolean stacked = false
		if itemid==single and GetUnitItem(u,box)!=null then  //single was picked up
			loop
				exitwhen inven>5
				set inv = UnitItemInSlot(u,inven)
				set n = GetItemCharges(inv) 
				set n2 = GetItemCharges(pick)
				if GetItemTypeId(inv)==box and n<max then
					if n2+n<=max then
						call SetItemCharges(inv,GetItemCharges(inv)+(GetItemCharges(pick)) )
						call RemoveItem(pick)
						set inven = 1337
					else
						call SetItemCharges(inv,max)
						call SetItemCharges(pick,n2-(max-n))
					endif
					set stacked = true
				endif
				set inven=inven+1
			endloop
			if stacked and (box=='I008' or box=='I009') then
				call PumpShotgun(u)
			elseif stacked and (box=='I00B' or box=='I00N') then
				call RifleBolt(u)
			endif
		elseif itemid==box then  //box was picked up
			set n = GetItemCharges(pick)
			if n<max then
				loop
					set inv = GetUnitItem(u,single)
					exitwhen inv==null or n>=max
					set n2 = GetItemCharges(inv)
					if n2+n<=max then
						call SetItemCharges(pick,GetItemCharges(pick)+n2)
						call RemoveItem(inv)
					else
						call SetItemCharges(pick,max)
						call SetItemCharges(inv,n2-(max-n))
					endif
					set n = GetItemCharges(pick)
				endloop
				set stacked = true
			endif
		endif
		set inv = null
		return stacked
	endfunction

	private function StackSame takes unit u, item pickedup, integer box, integer max returns boolean
		local integer A = 0
		local integer n
		local item titem
		if GetItemTypeId(pickedup)!=box then
			return false
		endif
		loop
			exitwhen A > 5
			set titem = UnitItemInSlot(u,A)
			if GetItemTypeId(titem)==box and titem!=pickedup then
				set n = GetItemCharges(pickedup)+GetItemCharges(titem)
				if n<=max then
					call SetItemCharges(titem,n)
					call RemoveItem(pickedup)
					set titem = null
					return true
				endif
			endif
			set A = A + 1
		endloop
		set titem = null
		return false
	endfunction

	private function ItemPickup takes unit u, item i returns nothing
		local integer A = 1
		local integer itemid = GetItemTypeId(i)
		loop
			exitwhen A>udg_nItemLists
			if CanPickup(u,itemid,udg_ItemLists[A]) then
				call UnitRemoveItem(u,i)
				return
			endif
			set A=A+1
		endloop
		//Stack(unit, item, item's itemid, box id,single id)
		if Stack(u,i,itemid,'shas','I006',8) then //ammo box, magazine
			return
		elseif Stack(u,i,itemid,'I008','I00C',24) then //Benelli, Shells
			return
		elseif Stack(u,i,itemid,'I009','I00C',32) then //Browning, Shells
			return
		elseif Stack(u,i,itemid,'I00B','I00D',10) then //XM29, Grenades
			return
		elseif Stack(u,i,itemid,'I00N','I00D',10) then //RMGL, Grenades
			return
		elseif Stack(u,i,itemid,'I00F','I00K',8) then //CE Case, CE
			return
		elseif Stack(u,i,itemid,'I00E','I00L',12) then //Clay Case, Clay
			return
		elseif StackSame(u,i,'I004',5) then //Medkit
			return
		elseif StackSame(u,i,'I006',3) then //Magazine
			return
		elseif StackSame(u,i,'I00C',16) then //Shells
			return
		elseif StackSame(u,i,'phea',3) then //Fibrin
			return
		elseif StackSame(u,i,'I00J',5) then //AV
			return
		elseif StackSame(u,i,'I010',5) then //Satchel Charge
			return
		elseif StackSame(u,i,'I00M',8) then //Ground Illumination Flare
			return
		elseif StackSame(u,i,'I00W',10) then //Flare Gun
			return
		elseif StackSame(u,i,'I00V',5) then //Smoke Grenade
			return
		endif
	endfunction

	

	private function DetachArmor takes unit u returns nothing
		call PolledWait(1.)
		call AttachSoundToUnit(gg_snd_DetachArmor,u)
		call SetSoundVolume(gg_snd_DetachArmor,127)
		call StartSound(gg_snd_DetachArmor)
		call PolledWait(0.65)
		call ShiftMoveSpeed(u,150.0)
	endfunction

	private function ItemDrop takes nothing returns nothing
		local unit u = GetTriggerUnit()
		local item n = GetManipulatedItem()
		local integer i = GetItemTypeId(n)
		local integer j = GetUnitTypeId(u)
		
		if (i == 'I002' or i == 'I007' or i == 'I000' or i == 'I00B' ) and ValidItem(u,n) then
			call SetUnitAbilityLevel(u, 'A00E', GetUnitAbilityLevel(u, 'A00E') - 1)
		endif
		
		if i == 'ckng' and ValidItem(u,n) then
			call SetUnitAbilityLevel(u, 'A00P', GetUnitAbilityLevel(u, 'A00P') - 1)
		endif
		
		if (i=='ckng' or i=='I002') and ValidItem(u,n) then  //Ammo Modifiers
			if j=='H003' or j=='z00F' or j=='z00G' then
				call UnitRemoveAbility(u,'A03S')
			else
				call UnitRemoveAbility(u,'A00A')
			endif
		elseif i=='I00O' and ValidItem(u,n) then //TX-1
			if j=='H003' or j=='z00F' or j=='z00G' then
				call UnitRemoveAbility(u,'A07Q')
			else
				call UnitRemoveAbility(u,'A07R')
			endif
		elseif i=='I007' and ValidItem(u,n) then //SAM-R
			call ShiftMoveSpeed(u,5.0)
			if j=='H003' or j=='z00F' or j=='z00G' then //Marksman
				call UnitRemoveAbility(u,'A00F')
			elseif j=='H008' or j=='z007' or j=='z005' then //Delta
				call UnitRemoveAbility(u,'A03S')
			elseif j=='H006' then //Recon
				call UnitRemoveAbility(u,'AItc')
			else
				call UnitRemoveAbility(u,'AItl')
			endif
		elseif i=='I018' and ValidItem(u,n) then //Marine Corpse
			call ShiftMoveSpeed(u,30.0)
		elseif i=='I00B' and ValidItem(u,n) then //M-29
			call ShiftMoveSpeed(u,4.0)
		elseif i=='I00N' and ValidItem(u,n) then //M320
			call ShiftMoveSpeed(u,3.0)
		elseif i=='I00I' and ValidItem(u,n) then //SMAW
			call ShiftMoveSpeed(u,6.0)
		elseif i=='I003' and ValidItem(u,n) then //Hecate
			call ShiftMoveSpeed(u,6.0)
		elseif i=='I000' and ValidItem(u,n) then //Machine Gun
			call ShiftMoveSpeed(u,10.0)
		elseif i=='I004' and ValidItem(u,n) then //Medkit
			call ShiftMoveSpeed(u,3.0)
		elseif i=='I008' and ValidItem(u,n) then //Benelli
			call ShiftMoveSpeed(u,5.0)
		elseif (i=='I009' or i=='I00X') and ValidItem(u,n) then //Browning and DAO
			call ShiftMoveSpeed(u,4.0)
		elseif i=='rde1' and ValidItem(u,n) then //Kevlar
			call ShiftMoveSpeed(u,-140.0) //10
			call DetachArmor(u)
		elseif i=='I001' and ValidItem(u,n) then //Composite
			call ShiftMoveSpeed(u,-138.0) //12
			call DetachArmor(u)
		elseif i=='I005' and ValidItem(u,n) then //Reactive
			call ShiftMoveSpeed(u,-134.0) //16
			call DetachArmor(u)
		elseif i=='I00Z' and ValidItem(u,n) then //Nano Body Armor
			call ShiftMoveSpeed(u,-138.0) //12
			call DetachArmor(u)
		elseif (i=='I00H' or i=='I017') and ValidItem(u,n) then //XML-9C and Surveillance Sentry
			call ShiftMoveSpeed(u,12.0)
		elseif i=='I00Q' or i=='I00R' or i=='I00P' then //Chaingun
			call ShiftMoveSpeed(u,35.0)
		elseif i=='I019' then //Aviation Fuel
			call ShiftMoveSpeed(u,40.0)
		endif
		set u = null
		set n = null
	endfunction



	private function WearArmor takes unit u returns nothing
		call PolledWait(1.5)
		call AttachSoundToUnit(gg_snd_WearArmor,u)
		call SetSoundVolume(gg_snd_WearArmor,127)
		call StartSound(gg_snd_WearArmor)
		call PolledWait(0.4)
		call ShiftMoveSpeed(u,150.0)
	endfunction


	private function ItemPickup2 takes nothing returns nothing
		local unit u = GetTriggerUnit()
		local player p = GetOwningPlayer(u)
		local item n = GetManipulatedItem()
		local integer i = GetItemTypeId(n)
		local integer j = GetUnitTypeId(u)
		local integer id = GetConvertedPlayerId(p)
		call ItemPickup(u,n)
		
		if (i == 'I002' or i == 'I007' or i == 'I000' or i == 'I00B' ) and UnitHasItem(u,n) then
			call SetUnitAbilityLevel(u, 'A00E', GetUnitAbilityLevel(u, 'A00E') + 1)
		endif
		
		if i == 'ckng' and UnitHasItem(u,n) then
			call SetUnitAbilityLevel(u, 'A00P', GetUnitAbilityLevel(u, 'A00P') + 1)
		endif
		
		if (i=='ckng' or i=='I002') and UnitHasItem(u,n) then //Ammo Modifiers
			call RifleBolt(u)
			if j=='H003' or j=='z00F' or j=='z00G' then
				call UnitAddAbility(u,'A03S')
			else
				call UnitAddAbility(u,'A00A')
			endif
		elseif i=='I00O' and UnitHasItem(u,n) then //TX-1
			call RifleBolt(u)
			if j=='H003' or j=='z00F' or j=='z00G' then
				call UnitAddAbility(u,'A07Q')
			else
				call UnitAddAbility(u,'A07R')
			endif
		elseif i=='I007' and UnitHasItem(u,n) then //SAM-R
			call RifleBolt(u)
			call ShiftMoveSpeed(u,-5.0)
			if j=='H003' or j=='z00F' or j=='z00G' then //Marksman
				call UnitAddAbility(u,'A00F')
			elseif j=='H008' or j=='z007' or j=='z005' then //Delta
				call UnitAddAbility(u,'A03S')
			elseif j=='H006' then //Recon
				call UnitAddAbility(u,'AItc')
			else
				call UnitAddAbility(u,'AItl')
			endif
		elseif i=='I018' and UnitHasItem(u,n) then //Marine Corpse
			call ShiftMoveSpeed(u,-30.0)
			call GeneralEquipment(u)
		elseif i=='I00B' and UnitHasItem(u,n) then //M-29
			call ShiftMoveSpeed(u,-4.0)
			call RifleBolt(u)
			if udg_Experience[id]<1000 then
				call DisplayTimedTextToPlayer(p,0.0,0.0,5.0,"Caution : M-29 grenades can harm friendlies")
			endif
		elseif i=='I00N' and UnitHasItem(u,n) then //M320
			call ShiftMoveSpeed(u,-3.0)
			call RifleBolt(u)
			if udg_Experience[id]<1000 then
				call DisplayTimedTextToPlayer(p,0.0,0.0,5.0,"Caution : M320 grenades can harm friendlies")
			endif
		elseif i=='I00I' and UnitHasItem(u,n) then //SMAW
			call ShiftMoveSpeed(u,-6.0)
			call RifleBolt(u)
			if udg_Experience[id]<1000 then
				call DisplayTimedTextToPlayer(p,0.0,0.0,5.0,"Caution : SMAW rockets can harm friendlies")
			endif
		elseif i=='I003' and UnitHasItem(u,n) then //Hecate
			call ShiftMoveSpeed(u,-6.0)
			call RifleBolt(u)
		elseif i=='I000' and UnitHasItem(u,n) then //Machine Gun
			call ShiftMoveSpeed(u,-10.0)
			call MachineGunLink(u)
		elseif i=='I004' and UnitHasItem(u,n) then //Medkit
			call ShiftMoveSpeed(u,-3.0)
			call GeneralEquipment(u)
		elseif i=='I008' and UnitHasItem(u,n) then //Benelli
			call ShiftMoveSpeed(u,-5.0)
			call PumpShotgun(u)
		elseif (i=='I009' or i=='I00X') and UnitHasItem(u,n) then //Browning and DAO
			call ShiftMoveSpeed(u,-4.0)
			call PumpShotgun(u)
		elseif i=='rde1' and UnitHasItem(u,n) then //Kevlar
			call ShiftMoveSpeed(u,-160.0) //10
			call GeneralEquipment(u)
			call WearArmor(u)
		elseif i=='I001' and UnitHasItem(u,n) then //Composite
			call ShiftMoveSpeed(u,-162.0) //12
			call GeneralEquipment(u)
			call WearArmor(u)
		elseif i=='I005' and UnitHasItem(u,n) then //Reactive
			call ShiftMoveSpeed(u,-166.0) //16
			call GeneralEquipment(u)
			call WearArmor(u)
		elseif i=='I00Z' and UnitHasItem(u,n) then //Nano Body Armor
			call ShiftMoveSpeed(u,-162.0) //12
			call GeneralEquipment(u)
			call WearArmor(u)
		elseif (i=='I00H' or i=='I017') and UnitHasItem(u,n) then //XML-9C and Surveillance Sentry
			call ShiftMoveSpeed(u,-12.0)
			call GeneralEquipment(u)
		elseif i=='I00Q' or i=='I00R' or i=='I00P' then //Chaingun
			call ShiftMoveSpeed(u,-35.0)
			call GeneralEquipment(u)
		elseif i=='I019' then //Aviation Fuel
			call ShiftMoveSpeed(u,-40.0)
			call GeneralEquipment(u)
		elseif (i=='I00N' or i=='I00I' or i=='I00B') and UnitHasItem(u,n) then
			call GeneralEquipment(u)
			if udg_Experience[id]<1000 then
				call DisplayTimedTextToPlayer(p,0.0,0.0,5.0,"Caution : Explosive weapons can harm friendlies")
			endif
		elseif UnitHasItem(u,n) then
			call GeneralEquipment(u)
		endif
		set u = null
		set n = null
	endfunction

	private function init takes nothing returns nothing
		local trigger t = CreateTrigger()
		call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
		call TriggerAddAction( t, function ItemPickup2 )
		
	    set t = CreateTrigger()
		call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DROP_ITEM)
		call TriggerAddAction( t, function ItemDrop )
	endfunction

endlibrary